//
//  SwiftCTRouter.swift
//  SwiftCTRouter
//
//  Created by Vencent on 2020/11/12.
//

import Foundation
/*
/// Target 名称
class TargetName: Target {
    required init() { }
    
    /// Action
    let Demo_ViewController: Action = { (params) in
        return UIViewController()
    }
    
    /// Action 带**Open_**前缀才可以使用 URL 调用。被 URL 调用时返回值不能为 nil，否则会被视为无法未响应
    let Open_Demo_ViewController: Action = { (params) in
        return UIViewController()
    }
}
 */
public protocol Target {
    init()
}
public typealias Action = ([String: Any])->Any?

public class SwiftCTRouter: NSObject {
    public static let `default` = SwiftCTRouter()
    private override init(){}
    
    /// 可响应的 schemes
    static var schemes: [String] = []
    /// 缓存
    lazy var tempTargetActions: [String: Action] = [:]
}

extension SwiftCTRouter {
    func performActionWithUrl(url: URL) -> Any? {
        let pathArray = url.path.components(separatedBy: "/")
        
        guard let components = URLComponents.init(url: url, resolvingAgainstBaseURL: false),
              let scheme = components.scheme,
              SwiftCTRouter.schemes.contains(scheme),
              let moduleName = components.host,
              !moduleName.isEmpty,
              pathArray.count > 0 else {
            return nil
        }
        
        let params = components.queryItems?.reduce([:], { (result, param) -> [String: Any] in
            guard let value = param.value else {
                return result
            }
            var r = result
            r[param.name] = value
            return r
        })
        
        let targetName: String?
        let actionName: String
        if pathArray.count > 1 {
            targetName = pathArray[0]
            actionName = pathArray[1..<pathArray.count].joined()
        }else {
            targetName = nil
            actionName = pathArray[0]
        }
        
        if actionName.hasPrefix("Public_"), let result = self.performTarget(module: moduleName, target: targetName, action: actionName, params: params) {
            return result
        }else {
            return nil
        }
    }
    
    func performTarget(module moduleName: String, target targetName: String? = nil, action actionName: String, params: [String: Any]? = nil) -> Any? {
        guard !moduleName.isEmpty && !actionName.isEmpty else {
            return nil
        }
        
        var className: String = moduleName + "."
        if targetName != nil && !targetName!.isEmpty {
            className += targetName!
        }else {
            className += moduleName
        }
        
        let tempKey = className + ">" + actionName
        if let property = self.tempTargetActions[tempKey] {
            return property(params ?? [:])
        }else if let tempClass = NSClassFromString(className) as? Target.Type {
            let target = tempClass.init()
            let mirror = Mirror(reflecting: target)
            if let property = mirror.children.first(where: { $0.label == actionName })?.value as? Action {
                self.tempTargetActions[tempKey] = property
                return property(params ?? [:])
            }else {
                return nil
            }
        }else {
            return nil
        }
    }
}






//static func performTarget(module moduleName: String? = nil, target targetName: String, action actionName: String, params: [String: Any]? = nil, isCacheTarget: Bool = false) -> Any? {
//    guard !targetName.isEmpty && !actionName.isEmpty else {
//        return nil
//    }
//
//    let className = "Target_" + targetName
//    let targetClass: AnyClass?
//    if let moduleName = moduleName , !moduleName.isEmpty {
//        let name = moduleName + "." + className
//        targetClass = NSClassFromString(name)
//    }else {
//        if let tempTarget = NSClassFromString(className) {
//            targetClass = tempTarget
//        }else {
//            targetClass = NSClassFromString(targetName + "." + className)
//        }
//    }
//
//    guard let tempClass = targetClass as? NSObject.Type else {
//        return nil
//    }
//    let target = tempClass.init()
//
//    let selectorName = actionName
//    let action = NSSelectorFromString(selectorName + ":")
//
//    if target.responds(to: action) {
//        let result = target.perform(action, with: params ?? [:])
//
//        return result?.takeUnretainedValue()
//    }else {
//        return nil
//    }
////        return self.sharedInstance().performTarget(targetName, action: actionName, params: nil, shouldCacheTarget: isCacheTarget)
//}
